﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;

namespace Sunny.Lib
{
    /// <summary>
    /// Regedit operation helper class
    /// It contains Find, insert ,delete operation
    /// </summary>
    public class RegEditHelper
    {
        #region Public function
        public static object GetKeyValue(string root, string subKeyPath, string findName)
        {
            // Check whether input parameter is correct
            if (string.IsNullOrEmpty(root))
            {
                return null;
            }
            if (string.IsNullOrEmpty(subKeyPath))
            {
                return null;
            }
            if (string.IsNullOrEmpty(findName))
            {
                return null;
            }

            // Get target key
            RegistryKey subKey = FindKey(root, subKeyPath);
            if (subKey == null)
            {
                return null;
            }

            // Get target key's value
            var findValue = subKey.GetValue(findName);

            return findValue;
        }

        public static bool InsertValue(string root, string subKeyPath, string name, string value)
        {
            // Check whether input parameter is correct
            if (string.IsNullOrEmpty(root))
            {
                return false;
            }
            if (string.IsNullOrEmpty(subKeyPath))
            {
                return false;
            }
            if (string.IsNullOrEmpty(name))
            {
                return false;
            }

            bool isSuccess = false;

            // Get target key
            RegistryKey subKey = FindKey(root, subKeyPath);
            if (subKey != null)
            {
                subKey.SetValue(name, value);
                isSuccess = true;
            }

            return isSuccess;
        }

        public static bool DeleteValue(string root, string subKeyPath, string name)
        {
            // Check whether input parameter is correct
            if (string.IsNullOrEmpty(root))
            {
                return false;
            }
            if (string.IsNullOrEmpty(subKeyPath))
            {
                return false;
            }

            bool isSuccess = false;

            // Get and Check target key is not null
            RegistryKey subKey = FindKey(root, subKeyPath);
            if (subKey != null)
            {
                // Get and Check Key value is not null
                if (GetKeyValue(root, subKeyPath, name) != null)
                {
                    subKey.DeleteValue(name);
                }

                isSuccess = true;
            }

            return isSuccess;
        }

        public static bool UpdateValue(string root, string subKeyPath, string name,string newValue)
        {
            // Check whether input parameter is correct
            if (string.IsNullOrEmpty(root))
            {
                return false;
            }
            if (string.IsNullOrEmpty(subKeyPath))
            {
                return false;
            }
            if (string.IsNullOrEmpty(name))
            {
                return false;
            }

            bool isSuccess = false;

            // Get target key
            RegistryKey subKey = FindKey(root, subKeyPath);
            if (subKey != null)
            {
                subKey.SetValue(name,newValue);
                isSuccess = true;
            }

            return isSuccess;
        } 
        #endregion

        #region Protect and Private function

        private static RegistryKey FindKey(string root, string subKeyPath)
        {
            //Check whether input parameter is correct
            if (string.IsNullOrEmpty(root))
            {
                return null;
            }
            if (string.IsNullOrEmpty(subKeyPath))
            {
                return null;
            }

            string findValueStr = string.Empty;

            // Find root key
            RegistryKey rootKey = GetRoot(root);
            if (rootKey == null)
            {
                return null;
            }

            // Find sub key
            RegistryKey findKey = rootKey.OpenSubKey(subKeyPath, false);

            return findKey;
        }

        private static RegistryKey GetRoot(string rootName)
        {
            if (rootName.Equals(RootKeyType.HKEY_CLASSES_ROOT.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                return Registry.ClassesRoot;
            }
            else if (rootName.Equals(RootKeyType.HKEY_CURRENT_CONFIG.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                return Registry.CurrentConfig;
            }
            else if (rootName.Equals(RootKeyType.HKEY_CURRENT_USER.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                return Registry.CurrentUser;
            }
            else if (rootName.Equals(RootKeyType.HKEY_LOCAL_MACHINE.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                return Registry.LocalMachine;
            }
            else if (rootName.Equals(RootKeyType.HKEY_USERS.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                return Registry.Users;
            }
            else
            {
                return null;
            }
        } 
        #endregion
    }

    public enum RootKeyType
    {
        HKEY_CLASSES_ROOT,
        HKEY_CURRENT_USER,
        HKEY_LOCAL_MACHINE,
        HKEY_USERS,
        HKEY_CURRENT_CONFIG
    }
}
